/**
 * 账单解析服务
 * 支持微信、支付宝账单的多种格式解析：CSV、Excel(XLS/XLSX)、PDF
 */

const Papa = require('papaparse');
const XLSX = require('xlsx');
const pdf = require('pdf-parse');
const fs = require('fs');

class BillParser {
  /**
   * 解析微信账单CSV
   * @param {string} csvContent - CSV文件内容
   * @returns {Array} 解析后的交易记录数组
   */
  static parseWeChatBill(csvContent) {
    try {
      // 微信账单CSV格式特点：前17行是说明文字，需要跳过
      const lines = csvContent.split('\n');
      const dataStartIndex = lines.findIndex(line => line.includes('交易时间'));
      
      if (dataStartIndex === -1) {
        throw new Error('无效的微信账单格式');
      }

      // 从数据开始行重新组合CSV
      const validCsv = lines.slice(dataStartIndex).join('\n');

      const result = Papa.parse(validCsv, {
        header: true,
        skipEmptyLines: true,
        encoding: 'utf-8'
      });

      if (result.errors.length > 0) {
        console.warn('解析警告:', result.errors);
      }

      return result.data.map((row, index) => {
        try {
          // 微信账单字段映射
          const amount = parseFloat(row['金额(元)']?.replace('¥', '') || 0);
          const incomeExpense = row['收/支']?.trim() || '';

          return {
            platform: 'wechat',
            transactionTime: row['交易时间']?.trim() || '',
            type: row['交易类型']?.trim() || '',
            counterparty: row['交易对方']?.trim() || '',
            product: row['商品']?.trim() || '',
            incomeExpense: incomeExpense,
            amount: amount,
            paymentMethod: row['支付方式']?.trim() || '',
            status: row['当前状态']?.trim() || '',
            transactionId: row['交易单号']?.trim() || '',
            merchantOrderId: row['商户单号']?.trim() || '',
            remark: row['备注']?.trim() || '',
            rowIndex: index
          };
        } catch (error) {
          console.error(`解析第${index + 1}行失败:`, error.message);
          return null;
        }
      }).filter(item => item !== null && item.transactionTime);

    } catch (error) {
      throw new Error('微信账单解析失败: ' + error.message);
    }
  }

  /**
   * 解析支付宝账单CSV
   * @param {string} csvContent - CSV文件内容
   * @returns {Array} 解析后的交易记录数组
   */
  static parseAlipayBill(csvContent) {
    try {
      // 支付宝账单CSV格式特点：前5行是说明文字，需要跳过
      const lines = csvContent.split('\n');
      const dataStartIndex = lines.findIndex(line => 
        line.includes('交易号') || line.includes('交易创建时间')
      );
      
      if (dataStartIndex === -1) {
        throw new Error('无效的支付宝账单格式');
      }

      // 从数据开始行重新组合CSV
      const validCsv = lines.slice(dataStartIndex).join('\n');

      const result = Papa.parse(validCsv, {
        header: true,
        skipEmptyLines: true,
        encoding: 'utf-8'
      });

      if (result.errors.length > 0) {
        console.warn('解析警告:', result.errors);
      }

      return result.data.map((row, index) => {
        try {
          // 支付宝账单字段映射（兼容多种格式）
          const amount = parseFloat(
            (row['金额（元）'] || row['金额'] || '0')
              .replace('¥', '')
              .replace(',', '')
          );
          const incomeExpense = (row['收/支'] || row['收支']).trim() || '';

          return {
            platform: 'alipay',
            transactionTime: (row['付款时间'] || row['交易创建时间'] || row['交易时间'])?.trim() || '',
            type: row['类型']?.trim() || '',
            counterparty: row['交易对方']?.trim() || '',
            product: row['商品名称']?.trim() || row['商品说明']?.trim() || '',
            incomeExpense: incomeExpense,
            amount: amount,
            status: row['交易状态']?.trim() || row['状态']?.trim() || '',
            transactionId: row['交易号']?.trim() || '',
            merchantOrderId: row['商家订单号']?.trim() || '',
            remark: row['备注']?.trim() || '',
            rowIndex: index
          };
        } catch (error) {
          console.error(`解析第${index + 1}行失败:`, error.message);
          return null;
        }
      }).filter(item => item !== null && item.transactionTime);

    } catch (error) {
      throw new Error('支付宝账单解析失败: ' + error.message);
    }
  }

  /**
   * 统一数据格式 - 将平台特定格式转换为系统标准格式
   * @param {Object} transaction - 平台交易记录
   * @returns {Object} 标准格式的交易记录
   */
  static normalizeTransaction(transaction) {
    try {
      // 判断收入/支出类型
      let type = 'expense';
      if (transaction.incomeExpense) {
        if (transaction.incomeExpense.includes('收入') || 
            transaction.incomeExpense.includes('收') ||
            transaction.incomeExpense === '收') {
          type = 'income';
        }
      }

      // 解析交易时间
      let transactionTime;
      try {
        const date = new Date(transaction.transactionTime);
        if (isNaN(date.getTime())) {
          transactionTime = new Date().toISOString().slice(0, 19).replace('T', ' ');
        } else {
          // 转换为MySQL DATETIME格式: YYYY-MM-DD HH:mm:ss
          transactionTime = date.toISOString().slice(0, 19).replace('T', ' ');
        }
      } catch (e) {
        transactionTime = new Date().toISOString().slice(0, 19).replace('T', ' ');
      }

      // 获取描述信息
      const description = transaction.product || transaction.counterparty || '未知交易';

      // 清理 raw_data，只保留可序列化的字段
      const cleanRawData = {
        platform: transaction.platform || '',
        transactionTime: transaction.transactionTime || '',
        type: transaction.type || '',
        counterparty: transaction.counterparty || '',
        product: transaction.product || '',
        incomeExpense: transaction.incomeExpense || '',
        amount: transaction.amount || 0,
        paymentMethod: transaction.paymentMethod || '',
        status: transaction.status || '',
        transactionId: transaction.transactionId || '',
        merchantOrderId: transaction.merchantOrderId || '',
        remark: transaction.remark || ''
      };

      return {
        type: type,
        amount: Math.abs(transaction.amount || 0),
        description: description,
        merchant: transaction.counterparty || '',
        transaction_time: transactionTime, // 已经是字符串格式
        platform: transaction.platform,
        platform_transaction_id: transaction.transactionId || '',
        payment_method: transaction.paymentMethod || '',
        status: transaction.status || '',
        raw_data: cleanRawData // 使用清理后的数据
      };
    } catch (error) {
      throw new Error('数据格式化失败: ' + error.message);
    }
  }

  /**
   * 批量统一格式
   * @param {Array} transactions - 交易记录数组
   * @returns {Array} 标准格式的交易记录数组
   */
  static normalizeTransactions(transactions) {
    return transactions.map(tx => this.normalizeTransaction(tx))
      .filter(tx => tx.amount > 0); // 过滤金额为0的记录
  }

  /**
   * 解析Excel文件（支持XLS和XLSX）
   * @param {string} filePath - Excel文件路径
   * @param {string} platform - 平台类型 ('wechat' | 'alipay')
   * @returns {Array} 解析后的交易记录数组
   */
  static parseExcel(filePath, platform) {
    try {
      // 读取Excel文件
      const workbook = XLSX.readFile(filePath, { 
        type: 'file',
        codepage: 65001 // UTF-8编码
      });

      // 获取第一个工作表
      const sheetName = workbook.SheetNames[0];
      const worksheet = workbook.Sheets[sheetName];

      // 微信账单特殊处理：跳过前面的说明行
      if (platform === 'wechat') {
        // 转换为二维数组，保留所有行
        const rawData = XLSX.utils.sheet_to_json(worksheet, { 
          header: 1, // 转为二维数组
          raw: false,
          defval: ''
        });

        console.log(`📊 Excel共 ${rawData.length} 行原始数据`);

        // 找到包含"交易时间"的那一行作为表头
        let headerRowIndex = -1;
        for (let i = 0; i < rawData.length; i++) {
          const row = rawData[i];
          if (row && row.some(cell => cell && cell.includes('交易时间'))) {
            headerRowIndex = i;
            break;
          }
        }

        if (headerRowIndex === -1) {
          throw new Error('未找到交易数据表头，请确认是微信账单文件');
        }

        console.log(`📋 找到表头在第 ${headerRowIndex + 1} 行`);

        // 提取表头和数据
        const headers = rawData[headerRowIndex];
        const dataRows = rawData.slice(headerRowIndex + 1);

        // 转换为对象数组
        const jsonData = dataRows.map(row => {
          const obj = {};
          headers.forEach((header, index) => {
            obj[header] = row[index] || '';
          });
          return obj;
        }).filter(row => {
          // 过滤掉空行或汇总行
          const firstCell = Object.values(row)[0];
          return firstCell && !firstCell.includes('总计') && !firstCell.includes('共');
        });

        console.log(`✅ 提取到 ${jsonData.length} 条有效数据`);

        return this.parseWeChatExcel(jsonData);

      } else {
        // 支付宝等其他平台正常解析
        const jsonData = XLSX.utils.sheet_to_json(worksheet, {
          raw: false,
          defval: ''
        });

        console.log(`📊 Excel解析成功，共 ${jsonData.length} 条记录`);

        if (platform === 'alipay') {
          return this.parseAlipayExcel(jsonData);
        } else {
          throw new Error('不支持的平台类型');
        }
      }

    } catch (error) {
      throw new Error('Excel文件解析失败: ' + error.message);
    }
  }

  /**
   * 解析微信Excel账单数据
   * @param {Array} jsonData - Excel转换的JSON数据
   * @returns {Array} 解析后的交易记录数组
   */
  static parseWeChatExcel(jsonData) {
    // 打印第一行的列名，用于调试
    if (jsonData.length > 0) {
      console.log('📋 Excel列名:', Object.keys(jsonData[0]));
      console.log('📋 第一行数据示例:', jsonData[0]);
    }
    
    return jsonData.map((row, index) => {
      try {
        // 兼容多种可能的列名格式
        const getField = (field, alternatives = []) => {
          const value = row[field];
          if (value !== undefined && value !== '') return value;
          for (const alt of alternatives) {
            const altValue = row[alt];
            if (altValue !== undefined && altValue !== '') return altValue;
          }
          return '';
        };

        const amountStr = getField('金额(元)', ['金额', '金额（元）', '交易金额']);
        const amount = parseFloat(amountStr.toString().replace(/[¥,]/g, '') || 0);

        return {
          platform: 'wechat',
          transactionTime: getField('交易时间', ['时间', '日期']),
          type: getField('交易类型', ['类型']),
          counterparty: getField('交易对方', ['对方', '商户']),
          product: getField('商品', ['商品名称', '商品说明']),
          incomeExpense: getField('收/支', ['收支']),
          amount: amount,
          paymentMethod: getField('支付方式', ['付款方式']),
          status: getField('当前状态', ['状态', '交易状态']),
          transactionId: getField('交易单号', ['单号']),
          merchantOrderId: getField('商户单号', ['订单号']),
          remark: getField('备注', ['说明']),
          rowIndex: index
        };
      } catch (error) {
        console.error(`解析第${index + 1}行失败:`, error.message);
        return null;
      }
    }).filter(item => {
      // 更宽松的过滤条件：只要不是null且金额大于0就保留
      if (item === null) return false;
      if (item.amount === 0) return false;
      // 即使没有时间字段也先保留，方便调试
      return true;
    });
  }

  /**
   * 解析支付宝Excel账单数据
   * @param {Array} jsonData - Excel转换的JSON数据
   * @returns {Array} 解析后的交易记录数组
   */
  static parseAlipayExcel(jsonData) {
    return jsonData.map((row, index) => {
      try {
        const getField = (field, alternatives = []) => {
          const value = row[field];
          if (value !== undefined && value !== '') return value;
          for (const alt of alternatives) {
            const altValue = row[alt];
            if (altValue !== undefined && altValue !== '') return altValue;
          }
          return '';
        };

        const amountStr = getField('金额（元）', ['金额', '金额(元)', '交易金额']);
        const amount = parseFloat(amountStr.toString().replace(/[¥,]/g, '') || 0);

        return {
          platform: 'alipay',
          transactionTime: getField('付款时间', ['交易创建时间', '交易时间', '时间']),
          type: getField('类型', ['交易类型']),
          counterparty: getField('交易对方', ['对方', '商户名称']),
          product: getField('商品名称', ['商品说明', '商品', '说明']),
          incomeExpense: getField('收/支', ['收支']),
          amount: amount,
          status: getField('交易状态', ['状态']),
          transactionId: getField('交易号', ['订单号']),
          merchantOrderId: getField('商家订单号', ['商户单号']),
          remark: getField('备注', ['说明']),
          rowIndex: index
        };
      } catch (error) {
        console.error(`解析第${index + 1}行失败:`, error.message);
        return null;
      }
    }).filter(item => item !== null && item.transactionTime);
  }

  /**
   * 解析PDF文件（主要用于支付宝账单）
   * @param {string} filePath - PDF文件路径
   * @param {string} platform - 平台类型
   * @returns {Array} 解析后的交易记录数组
   */
  static async parsePDF(filePath, platform) {
    try {
      // 读取PDF文件
      const dataBuffer = fs.readFileSync(filePath);
      
      // 解析PDF文本
      const pdfData = await pdf(dataBuffer);
      const text = pdfData.text;

      console.log(`📄 PDF解析成功，共 ${pdfData.numpages} 页`);

      // 根据平台解析不同格式
      if (platform === 'alipay') {
        return this.parseAlipayPDF(text);
      } else {
        throw new Error('目前仅支持支付宝PDF账单');
      }

    } catch (error) {
      throw new Error('PDF文件解析失败: ' + error.message);
    }
  }

  /**
   * 解析支付宝PDF账单文本
   * @param {string} text - PDF文本内容
   * @returns {Array} 解析后的交易记录数组
   */
  static parseAlipayPDF(text) {
    try {
      const transactions = [];
      const lines = text.split('\n');
      
      // 支付宝PDF格式通常每笔交易占多行
      // 示例格式：
      // 2024-01-15 14:30:25 | 商家名称 | 支出 | ￥50.00 | 余额支付 | 交易成功
      
      let currentTransaction = null;
      
      for (let i = 0; i < lines.length; i++) {
        const line = lines[i].trim();
        if (!line) continue;

        // 检测时间格式 (YYYY-MM-DD HH:mm:ss 或 YYYY/MM/DD HH:mm:ss)
        const timeMatch = line.match(/(\d{4}[-\/]\d{2}[-\/]\d{2}\s+\d{2}:\d{2}:\d{2})/);
        
        if (timeMatch) {
          // 新的交易记录开始
          if (currentTransaction) {
            transactions.push(currentTransaction);
          }

          // 尝试提取一行中的所有信息
          const parts = line.split(/[|｜]/); // 支持中英文分隔符
          
          currentTransaction = {
            platform: 'alipay',
            transactionTime: timeMatch[1],
            counterparty: '',
            product: '',
            incomeExpense: '',
            amount: 0,
            status: '',
            transactionId: '',
            merchantOrderId: '',
            remark: '',
            rowIndex: transactions.length
          };

          // 解析各个字段
          if (parts.length >= 4) {
            currentTransaction.counterparty = parts[1]?.trim() || '';
            currentTransaction.incomeExpense = parts[2]?.trim() || '';
            
            const amountStr = parts[3]?.trim() || '0';
            currentTransaction.amount = parseFloat(amountStr.replace(/[￥¥,]/g, ''));
            
            if (parts.length >= 5) {
              currentTransaction.paymentMethod = parts[4]?.trim() || '';
            }
            if (parts.length >= 6) {
              currentTransaction.status = parts[5]?.trim() || '';
            }
          }
        } else if (currentTransaction) {
          // 补充交易信息（商品名称、订单号等可能在后续行）
          if (line.includes('商品') || line.includes('备注')) {
            currentTransaction.product += ' ' + line;
          }
          if (line.match(/\d{15,}/)) { // 交易号通常是长数字
            currentTransaction.transactionId = line.match(/\d{15,}/)[0];
          }
        }
      }

      // 添加最后一笔交易
      if (currentTransaction) {
        transactions.push(currentTransaction);
      }

      console.log(`📊 从PDF中提取 ${transactions.length} 条交易记录`);
      
      return transactions.filter(tx => tx.amount > 0);

    } catch (error) {
      throw new Error('支付宝PDF解析失败: ' + error.message);
    }
  }

  /**
   * 统一入口 - 根据文件类型自动选择解析方法
   * @param {string} filePath - 文件路径
   * @param {string} platform - 平台类型 ('wechat' | 'alipay')
   * @returns {Array} 解析后的交易记录数组
   */
  static async parseFile(filePath, platform) {
    const ext = filePath.toLowerCase().split('.').pop();

    try {
      let transactions;

      if (ext === 'csv') {
        // CSV文件
        const content = fs.readFileSync(filePath, 'utf-8');
        if (platform === 'wechat') {
          transactions = this.parseWeChatBill(content);
        } else if (platform === 'alipay') {
          transactions = this.parseAlipayBill(content);
        } else {
          throw new Error('不支持的平台类型');
        }
      } else if (ext === 'xls' || ext === 'xlsx') {
        // Excel文件
        transactions = this.parseExcel(filePath, platform);
      } else if (ext === 'pdf') {
        // PDF文件
        transactions = await this.parsePDF(filePath, platform);
      } else {
        throw new Error('不支持的文件格式: ' + ext);
      }

      console.log(`✅ ${platform} 账单解析完成，共 ${transactions.length} 条记录`);
      return transactions;

    } catch (error) {
      console.error('文件解析错误:', error);
      throw error;
    }
  }
}

module.exports = BillParser;

